#ifndef __MENUPRINCIPAL_H__
#define __MENUPRINCIPAL_H__

#include <iostream>
#include <string>
#include "Fichero.h"
#include "Producto.h"

using namespace std;

class CMenuPrincipal
{
private:
	CFichero	fichero;
	void inspeccionar();
	void exportar();
	void buscar();
	void eliminar();
	void modificar();
	void editar(string codigo,CProducto	&producto,int nroProducto);
	void insertar();
	void opcAbrir();
	void opcCrear();
	char submenu(string operacion,string &clave);
	bool validarEntero(string &numero, unsigned int longitud);
	bool validarPrecio(string &numero);
	void insPorNodo();
	void insPorBloque();
	void insPorBloque(string indice);
public:
	CMenuPrincipal(int argc, char *argv[]);
	~CMenuPrincipal(void);
	void ejecutar();
	void menu();
};
/*-----------------------------------------------------------*/
CMenuPrincipal::CMenuPrincipal(int argc, char *argv[]):fichero(argc,argv)
{
	fichero.procesar();
}
/*-----------------------------------------------------------*/
CMenuPrincipal::~CMenuPrincipal(void)
{
}
/*-----------------------------------------------------------*/
void CMenuPrincipal::ejecutar()
{
}
/*-----------------------------------------------------------*/
void CMenuPrincipal::menu()
{
  cout<<"--------------------------------------------"<<endl;
  string opcion;
  bool exit = false;
  fichero.inicializarCtoProc(); //(CTO_PROC)
  while (!exit)
  {
		//system("clear"); En linux    
		cout<<endl;
		cout<<"--------------------------------------------"<<endl;
		cout<<"          ***  Menu Principal  ***          "<<endl;
		cout<<"--------------------------------------------"<<endl;
		cout<<"1- Insertar un Producto"<<endl;
		cout<<"2- Eliminar un Producto"<<endl;
		cout<<"3- Buscar un Producto"<<endl;
		cout<<"4- Inspeccionar Archivos"<<endl;
		cout<<"5- Exportar el Archivo"<<endl;
		cout<<"6- Salir"<<endl;	
		cout<<endl;
		cout<<"Opcion: "; 
		getline(cin,opcion);
		cout<<endl;
		if (validarEntero(opcion,1))
		switch (opcion[0])
		{
			case '1': insertar(); break;
			case '2': eliminar(); break;
			case '3': buscar(); break;
			case '4': inspeccionar(); break;
			case '5': exportar(); break;
			case '6': exit= true; break;
			default: cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
		}
		else cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
  }
}
/*-----------------------------------------------------------*/
//Si longitud es = 0 valida un entero de cualquier longitud
//si no valida uno que tenga esa longitud
bool CMenuPrincipal::validarEntero(string &numero, unsigned int longitud)
{	
	int error;
	bool valido = true;
	string caracter;
	if ((numero.length() > longitud && longitud!=0) || numero.length()==0) valido = false;
	for (unsigned int i=0; i<numero.length(); i++)
	{
	  caracter="";	
	  caracter.append(1,numero[i]);
	  error = atoi(caracter.c_str());		
  	  //si la conversion di� error(0) y no era un 0 lo que queria convertir
	  if (error == 0 && caracter.compare("0")!=0) valido = false;
	}
	return valido;
}

/*-----------------------------------------------------------*/
bool CMenuPrincipal::validarPrecio(string &numero)
{	
	double error;
	int cantPuntos = 0;
	bool valido = true;
	string caracter;
	if (numero.length()==0 ) valido = false;
	for (unsigned int i=0; i<numero.length(); i++)
	{
	  caracter="";	
	  caracter.append(1,numero[i]);
	  error = atof(caracter.c_str());		
	  //si la conversion di� error(0) y no era un 0 lo que queria convertir
	  if (error == 0 && caracter.compare("0")!=0) 
	  {
	  	  //Si no se pudo convertir el caracter da error, salvo que
	  	  //sea un punto y este sea el unico y no este al principio del string
		  if (caracter.compare(".")==0 && cantPuntos<1 && i!=0)
			cantPuntos++;
		  else
			valido = false;
	  }		  
	}
	//Si el ultimo caracter es un punto lo elimino y dejo la parte entera
	if (numero[numero.length()-1] =='.') numero = numero.substr(0,numero.length()-1);
	return valido;
}

/*-----------------------------------------------------------*/
//template <class CClave >
char CMenuPrincipal::submenu(string operacion,string &clave)
{
	cout<<"1- "+operacion+" por Codigo del Producto"<<endl;
	cout<<"2- "+operacion+" por Nombre del Producto"<<endl;
	cout<<"3- "+operacion+" por Marca del Producto"<<endl;
	cout<<"4- "+operacion+" por Nombre y Marca del Producto"<<endl;
	cout<<"5- Salir"<<endl;
	clave="";
	string  opcion;
	bool exit = false;
	while (!exit)
	{
		cout<<endl;
		cout<<"Opcion: "; 
		getline(cin,opcion);
		cout<<endl;
		if (validarEntero(opcion,1))
		switch (opcion[0])	
		{
			case '1': 
			{
				exit=true; 
				do{
					cout<<"Ingrese el Codigo del Producto: ";				
					getline(cin,clave);
				}while (!validarEntero(clave, 5));
				break;
			}
			case '2':
			{
				exit=true; 
				cout<<"Ingrese el Nombre del Producto: ";
				getline(cin,clave);
				break;
			}
			case '3':
			{
				exit=true; 
				cout<<"Ingrese la Marca del Producto: ";
				getline(cin,clave);
				break;	
			}
			case '4':
			{
				exit=true; 
				string claveAux="";
				clave ="00000";//esto es para inicializar el codigo para el contructor de candidata. (es medio trucho jaja)
				cout<<"Ingrese la Marca del Producto: ";
				getline(cin,claveAux);
				clave += convertirChar((TIPO_DATO)claveAux.length(),TAMANIO_BYTE_DIN);
				clave+=claveAux;				
				cout<<"Ingrese el Nombre del Producto: ";
				getline(cin,claveAux);
				clave +=convertirChar((TIPO_DATO)claveAux.length(),TAMANIO_BYTE_DIN);
				clave+=claveAux;
//				cout<<"Ingrese el Nombre y la Marca del Producto: ";

//				getline(cin,clave);
				break;
			}
			case '5':exit=true;
				break;
			default: cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
		}
		else cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
	}
	return opcion[0];	
}
/*----------------------------------------------------------------
------- Metodos de Insertar --------------------------------------
----------------------------------------------------------------*/
void CMenuPrincipal::opcCrear()
{
	string nomArchivo;
	string codigo="", nombre="", marca="", presentacion="", precio="",aux="";
	CProducto	registro;
	
	//cout<<"Ingrese el nombre del archivo: "; 
	//getline(cin,nomArchivo);
	string exit="S";
	while (exit[0]=='S')
	{
		this->fichero.inicializarCtoProc();//(CTO_PROC)
		codigo=""; nombre=""; marca=""; presentacion=""; precio="";	aux="";
		cout<<endl;
		cout<<" *** Nuevo Producto *** "<<endl;	 	
		do{
			cout<<"Codigo del Producto: ";
			getline(cin,codigo);
		}while (!validarEntero(codigo, 5));
		
		registro.setRegCodProd(codigo);
		
		cout<<"Marca del Producto: "; 
		cin>>marca;	
		getline(cin,aux,'\n');
		registro.setRegMarca(marca+aux);

		cout<<"Nombre del Producto: "; 
		cin>>nombre;	
		getline(cin,aux,'\n');		
		registro.setRegNombre(nombre+aux);

		registro.setRegCantPres(1);
		cout<<"Presentacion del Producto: "; 
		cin>>presentacion;
		getline(cin,aux,'\n');		
		registro.setRegPresentacion(presentacion+aux);
		
		do{
			cout<<"Precio del Producto: "; 	
			getline(cin,precio);
		}while (!validarPrecio(precio));
		registro.setRegPrecio(precio);				
		//primitiva para cargar buffer de 1024bytes
		fichero.insertar(registro.getRegistro());
		fichero.mostrarCtoProc(); //(CTO_PROC)
		cout<<endl;
		do{
			cout<<"Desea ingresar otro producto?(S/N): "; 
			getline(cin,exit);
			exit[0] = toupper(exit[0]);
		}while(exit.length()!=1 || (exit[0]!='S' && exit[0]!='N'));
		
	}
}
/*-----------------------------------------------------------*/
void CMenuPrincipal::opcAbrir()
{
	string cantReg;
	do{
		cout<<"Ingrese la cantidad de registros que desea cargar: "; 
		getline(cin,cantReg);
	}while (!validarEntero(cantReg, 0));
	cout<<endl;
	//cargo registros
	//generarArchivosDatos(cantReg);	
}
/*-----------------------------------------------------------*/
void CMenuPrincipal::insertar()
{	
	//char opcion;	
//	bool exit = false;
//	while (!exit)
	{
		//cout<<endl;
		//cout<<"Desea Crear un archivo nuevo o Abrir uno existente?(C/A): ";
	//	cin>>opcion;
//		cout<<endl;
/*		switch (toupper(opcion))
		{
			case 'C': exit=true; opcCrear(); break;
			//case 'A': exit=true; opcAbrir(); break;
			default: cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
		}
*/		opcCrear(); 
			//case 'A': exit=true; opcAbrir(); break;
		//cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;

	}
}
/*----------------------------------------------------------------
------- Metodos de Modificar--------------------------------------
----------------------------------------------------------------*/
void CMenuPrincipal::editar(string codigo,CProducto	&producto,int nroProducto)
{		
		string clave="";//,salir="S";
		//primitivas para buscar un producto en todos los archivos
		//primitivas para eliminar un producto en todos los archivos
		string nombre, marca, presentacion, precio;
		cout<<" *** Modificar Producto *** "<<endl;	
		cout<<" *** Elija una opcion *** "<<endl;	
		cout<<"1- Agregar un presentacion."<<endl;
		cout<<"2- Quitar un presentacion."<<endl;
		cout<<"3- Cambiar un precio."<<endl;
		cout<<"4- Salir"<<endl;
		clave="";
		string  opcion;
		bool exit = false;
		while (!exit)
		{
			cout<<endl;
			cout<<"Opcion: "; 
			getline(cin,opcion);
			cout<<endl;
			if (validarEntero(opcion,1))		
			switch (opcion[0])	
			{
				case '1': //AGREGAR UNA PRESENTACION
				{
					exit=true;

					producto.setRegCodProd(codigo);		
					producto.setRegNombre("Nombre");		
					producto.setRegMarca("Marca");
					producto.setRegCantPres(1);
					//Aca antes podria mostrar la presentacion que tenia antes
					cout<<"Ingrese la nueva presentacion del Producto: ";
					getline(cin,presentacion);
					producto.setRegPresentacion(presentacion);
					do{
						cout<<" Nuevo precio del Producto: "; 
						getline(cin,precio);
					}while (!validarPrecio(precio));
					producto.setRegPrecio(precio);
					fichero.insertar(producto.getRegistro());					
					break;
				}
				case '2'://QUITAR UNA PRESENTACION
				{
					exit=true; 
					do{
						cout<<"Ingrese el numero de presentacion a quitar."<<endl;
						getline(cin,clave);
					}while (!validarEntero(clave, 1) );
					//producto.eliminarPresentacion(atoi(clave.c_str()));
					fichero.eliminarPresentacion(codigo,atoi(clave.c_str()),nroProducto);
					//quitar la presentacion
					break;
				}
				case '3'://MODIFICAR EL PRECIO DE UN REGISTRO
				{
					exit=true; 					
						
					do{
//						do{
							cout<<"Ingrese el numero de precio a cambiar."<<endl;
							getline(cin,clave);
//						}while(producto.getTamanioLista()< atoi(clave.c_str()));
					}while (!validarEntero(clave, 1));
					do{
						cout<<"Ingrese el precio nuevo: "; 
						getline(cin,precio);
					}while (!validarPrecio(precio));
					//producto.setRegPrecio(atoi(clave.c_str()),precio);
					fichero.modificarPrecio(codigo,atoi(clave.c_str()),nroProducto,precio);
					break;	
				}
				case '4':exit=true; 
			}

	//		do{
	//			cout<<"Desea modificar otro producto?(S/N): "; 
	//			getline(cin,salir);
	//			salir[0] = toupper(salir[0]);
	//		}while(salir.length()!=1 || (salir[0]!='S' && salir[0]!='N'));

		}

/*

		producto.setRegCodProd(codigo);
		cout<<"Nombre del Producto: ";getline(cin,nombre);
		producto.setRegNombre(nombre);
		cout<<"Marca del Producto: ";getline(cin,marca);	
		producto.setRegMarca(marca);
		cout<<"Presentacion del Producto: ";getline(cin,presentacion);
		producto.setRegPresentacion(presentacion);
		do{
			cout<<"Precio del Producto: "; 
			getline(cin,precio);
		}while (!validarPrecio(precio));
		producto.setRegPrecio(precio);
*/		
		//primitivas para insertar un producto en todos los archivos
}
/*-----------------------------------------------------------*/
void CMenuPrincipal::modificar()
{
	string exit="S";
	TIPO_DATO nroBloque=0;
	while (exit[0]=='S')
	{
		string codigo;
		do{			
			cout<<"Ingrese el Codigo del Producto a modificar: "; 
			getline(cin,codigo);
			cout<<endl;
		}while (!validarEntero(codigo, 5));
		if(this->fichero.buscarPrimaria(codigo,nroBloque))
		{
			CProducto	producto;
			
//			editar(codigo,producto);		
			cout<<endl;
			//CClavePrimaria	primaria(producto.getRegistro(),nroBloque);
			fichero.modificar(producto,nroBloque);
		}
		else
			cout<<"El codigo de producto que ingreso no existe."<<endl;
		do{
			cout<<"Desea modificar otro producto?(S/N): "; 
			getline(cin,exit);
			exit[0] = toupper(exit[0]);
		}while(exit.length()!=1 || (exit[0]!='S' && exit[0]!='N'));
	}
}
/*----------------------------------------------------------------
------- Metodos de Eliminar --------------------------------------
----------------------------------------------------------------*/
void CMenuPrincipal::eliminar()
{
	string clave="",aux="";
	char opc = submenu("Eliminar", clave);
	bool exit = false;
	this->fichero.inicializarCtoProc(); //(CTO_PROC)	
	while (!exit)
	{
		switch (opc)
		{
			case '1': exit=true; fichero.eliminarPrimaria(clave); break;//Eliminar por Codigo del Producto
			case '2': 
				exit=true; 
				aux=(string)"00000"+convertirChar(5,TAMANIO_BYTE_DIN)+(string)"MARCA"+convertirChar((int)clave.length(),TAMANIO_BYTE_DIN)+clave;
				fichero.eliminarSecNombre(aux);
				break;//Eliminar por Nombre del Producto		
			case '3': 
				exit=true; 
				aux=(string)"00000"+convertirChar((int)clave.length(),TAMANIO_BYTE_DIN)+clave+convertirChar(6,TAMANIO_BYTE_DIN)+(string)"NOMBRE";
				fichero.eliminarSecMarca(aux);
				break;//Eliminar por Marca del Producto
			case '4': exit=true; fichero.eliminarCandidata(clave);break;//Eliminar por Nombre y Marca del Producto
			case '5': exit=true; break;
			default: cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
		}
	}
}
/*----------------------------------------------------------------
------- Metodos de Buscar ----------------------------------------
----------------------------------------------------------------*/
void CMenuPrincipal::buscar()
{	
	list<CProducto*>			productos;
	list<CProducto*>::iterator	it;
	string clave;
	string aux="";
	fichero.clear();
	char opc = submenu("Buscar", clave);
	bool exit = false;
	while (!exit)
	{
		switch (opc)
		{
			case '1': 
				exit=true; 
				fichero.buscarPrimaria(clave,productos);				
				break;//Buscar por Codigo del Producto
			case '2': exit=true;
				
				aux=(string)"00000"+convertirChar(5,TAMANIO_BYTE_DIN)+(string)"MARCA"+convertirChar((int)clave.length(),TAMANIO_BYTE_DIN)+clave;								
				fichero.buscarSecNombre(aux,productos);
				break;//Buscar por Nombre del Producto		

			case '3':
				exit=true; 
				aux=(string)"00000"+convertirChar((int)clave.length(),TAMANIO_BYTE_DIN)+clave+convertirChar(6,TAMANIO_BYTE_DIN)+(string)"NOMBRE";
				fichero.buscarSecMarca(aux,productos);
				break;//Buscar por Marca del Producto
			case '4': exit=true; fichero.buscarCandidata(clave,productos);break;//Buscar por Nombre y Marca del Producto
			case '5': exit=true; break;
			default: cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
		}
	}
	for(it=productos.begin();it!=productos.end();it++)
	{
		cout<<"Codigo del producto: "<<(*it)->getCodProd()<<endl;
		cout<<"Marca del producto: "<<(*it)->getMarca()<<endl;
		cout<<"Nombre del producto: "<<(*it)->getNombre()<<endl<<endl;
		(*it)->mostrarLista(std::cout);
//		cout<<"Presentaci�n del producto: "<<(*it)->getPresentacion()<<endl;
//		cout<<"Precio del producto: "<<(*it)->getPrecio()<<endl;
	}
	
	this->fichero.mostrarCtoProc(); //(CTO_PROC)
		
	//imprimo el produco
	string codigo,retirada="";//esto me lo va a devolver la busqueda
	string opcion;
	bool salir=false;
	int contador=0;
	CProducto	productoAux;	
	//TIPO_DATO nroBloque;
	for(it=productos.begin();it!=productos.end() && !salir;it++)
	{
		exit = false;
		while (!exit)
		{
			cout<<endl;
/*B++*/		cout<<"\nQue desea hacer con el codigo de producto :"<<(*it)->getCodProd()<<" .- "<<endl;
			cout<<"Desea (E)liminar o (M)odificar el producto encontrado, \n(R)epetir la busqueda o (S)alir de la consulta?(E/M/R/S): ";		
			getline(cin,opcion);
			cout<<endl;
			//Si no ingreso una letra fuerzo el error
			if (opcion.length()!=1) opcion[0]='X';
			switch (toupper(opcion[0]))
			{
				case 'E': exit=false; this->eliminar();/*Elimino*/ break;
				case 'M': exit=false;
					editar((*it)->getCodProd(),productoAux,contador);		
					cout<<endl;
					break;
				case 'R': exit=true; buscar(); salir=true; break;
				case 'S': exit=true; salir=true;  break;
				default: cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
			}
			//si elige una busqueda o elige salirno hago la pregunta.
			if(!exit)
			{
				do{
					cout<<"Desea realizar otra accion sobre el producto?(S/N): "; 
					getline(cin,retirada);
					retirada[0] = toupper(retirada[0]);
				}while(retirada.length()!=1 || (retirada[0]!='S' && retirada[0]!='N'));
				if(retirada!="S")
					exit=true;
				else
					exit=false;
			}
		}
		contador++;
	}
	fichero.clear();
	for(it=productos.begin();it!=productos.end() ;it++)
		delete (*it);
}
/*----------------------------------------------------------------
------- Metodos de Inspeccionar ----------------------------------
----------------------------------------------------------------*/
void CMenuPrincipal::inspeccionar()
{
	this->fichero.inicializarCtoProc(); //(CTO_PROC)
	string opcion;
	cout<<"Elija el indice que quiere usar:"<<endl;
	cout<<"1- Indice Primario"<<endl;
	cout<<"2- Indice Secundario Nombre"<<endl;
	cout<<"3- Indice Secundario Marca"<<endl;
	cout<<"4- Indice clave candidata"<<endl;
	cout<<"5- Salir"<<endl;

	bool exit = false;
	int nroOpc = 0;
	while (!exit)
	{
		cout<<endl;
		cout<<"Opcion: "; 
		getline(cin,opcion);
		cout<<endl;
		if (validarEntero(opcion,1))
		{
			nroOpc = atoi(opcion.c_str());
			if( nroOpc > 0 && nroOpc < 5)
			{
				insPorBloque(opcion);
				exit=true;
			}else 
			if (nroOpc == 5)
				exit = true;			 
		}			
		else cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
	}
	this->fichero.mostrarCtoProc(); //(CTO_PROC)
}

/*-----------------------------------------------------------
void CMenuPrincipal::inspeccionar()
{
	insPorBloque();
}
 ESTE NO PREGUNTA Y SOLO HACE EL PRIMARIO*/
/*-----------------------------------------------------------*/
void CMenuPrincipal::insPorNodo()
{
	string numero;
	do{
		cout<<"Ingrese el numero de Nodo: ";	
		getline(cin,numero);
	}while (!validarEntero(numero, 0));
	cout<<endl;
}
/*-----------------------------------------------------------*/
void CMenuPrincipal::insPorBloque()
{
	string numero;
	do{
		cout<<"Ingrese el numero de Bloque: ";	
		getline(cin,numero);
	}while (!validarEntero(numero, 0));
	cout<<endl;
	fichero.leerBloque(atoi(numero.c_str()));
}

/*-----------------------------------------------------------*/
void CMenuPrincipal::insPorBloque(string indice)
{
	string numero;
	do{
		cout<<"Ingrese el numero de Bloque: ";	
		getline(cin,numero);
	}while (!validarEntero(numero, 0));
	cout<<endl;
	fichero.leerBloque(indice, atoi(numero.c_str()));
}

/*----------------------------------------------------------------
------- Metodos de Exportar ----------------------------------
----------------------------------------------------------------*/
void CMenuPrincipal::exportar()
{
	string opcion;

	cout<<"1- Exportar por Codigo del Producto"<<endl;
	cout<<"2- Exportar por Nombre del Producto"<<endl;
	cout<<"3- Exportar por Marca del Producto"<<endl;
	cout<<"4- Exportar por Nombre y Marca del Producto"<<endl;
	cout<<"5- Salir"<<endl;

	bool exit = false;
	int nroOpc = 0;
	while (!exit)
	{
		cout<<endl;
		cout<<"Opcion: "; 
		getline(cin,opcion);
		cout<<endl;
		if (validarEntero(opcion,1))
		{
			nroOpc = atoi(opcion.c_str());
			if( nroOpc > 0 && nroOpc < 5)
			{
				fichero.exportarArchivo(opcion);
				exit=true;
			}else 
			if (nroOpc == 5)
				exit = true;			 
		}			
		else cout<<"<<No existe la opcion ingresada, por favor intentelo de nuevo>>"<<endl;
	}	
}
/*-----------------------------------------------------------*/
#endif //__MENUPRINCIPAL_H__

